# 爬取《青春有你3》中所有参赛选手信息
import json
import pandas as pd
import requests
from bs4 import BeautifulSoup


# 将字典存为csv 传入的是list格式
# DataFrame 是一个表格型的数据结构，它含有一组有序的列，每列可以是不同的值类型
def dic_to_csv(dic_data):
    pd.DataFrame(list(dic_data)).to_csv('persons.csv')


# 将字典列表导出为Excel文件 传入的是list格式
def export_excel(dic_data):
    # 将列表转换为DataFrame
    pf = pd.DataFrame(list(dic_data))
    # 指定字段顺序
    order = ['name', 'link', 'zone', 'height', 'weight', 'company']
    # pandas.DataFrame(data, index, columns, dtype, copy)
    # 其中columns是一个list事列名 index：索引值，或者可以称为行标签
    pf = pf[order]
    # 选择多列
    # subset = pf[['Name', 'Age']]
    # 将列名替换为中文
    columns_map = {
        'name': '选手姓名',
        'link': '选手链接',
        'zone': '来自所属',
        'height': '身高',
        'weight': '体重',
        'company': '经济公司'
    }
    pf.rename(columns=columns_map, inplace=True)
    # inplace = True：不创建新的对象，直接对原始对象进行修改；
    # inplace = False：对数据进行修改，创建并返回新的对象承载其修改结果。
    # 指定生成的Excel表格名称
    file_path = pd.ExcelWriter('persons.xlsx')
    # 替换空单元格
    pf.fillna(' ', inplace=True)
    # 输出
    pf.to_excel(file_path, encoding='utf-8', index=False)
    # 保存表格
    file_path.save()


def catch_html_data():
    headers = {
        # 在F12的网络的第一个文件的User-Agent查找
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0 '
    }
    url = 'https://baike.baidu.com/item/%E9%9D%92%E6%98%A5%E6%9C%89%E4%BD%A0%E7%AC%AC%E4%B8%89%E5%AD%A3/51140980'

    try:
        response = requests.get(url, headers=headers)
        print(response.status_code)  # 响应状态码，200表示成功
        # 将一段文档传入BeautifulSoup的构造方法,就能得到一个文档的对象, 可以传入一段字符串
        soup = BeautifulSoup(response.text, 'lxml')  # 解析内容,解析器

        h3s = soup.find_all("h3")
        table = None
        for h3 in h3s:
            if "参赛选手" in h3:
                h3_table = h3
                table = h3_table.find_next("table")
        return table

    except Exception as e:
        print(e)


# 对爬取的页面数据进行解析，并保存为JSON文件
def parse_html_data(table_html):
    context_html = BeautifulSoup(str(table_html), 'lxml')
    all_trs = context_html.find_all('tr')
    persons = []
    # 这里只提取了td，没有th
    for tr in all_trs[1:]:
        all_tds = tr.find_all('td')
        person = {"name": all_tds[0].text,  # 选手姓名
                  "link": 'https://baike.baidu.com' + all_tds[0].find('a').get('href'),  # 个人百度百科链接
                  "zone": all_tds[1].text,  # 来自所属
                  "height": all_tds[2].text,  # 身高
                  "weight": all_tds[3].text,  # 体重
                  "company": all_tds[4].text  # 经济公司
                  }
        persons.append(person)

    dic_to_csv(persons)  # 保存为csv格式
    export_excel(persons)  # 保存为excel格式

    json_data = json.loads(str(persons).replace("\'", "\""))
    # 需要将'转换为"，不然如果'在"内的时候会报错
    # json.loads()是针对内存对象，将string转换为dict
    # json.load()针对文件句柄，将json格式的字符转换为dict，
    with open('persons' + '.json', 'w', encoding='UTF-8') as file:
        json.dump(json_data, file, ensure_ascii=False, indent=2)
        # indent: 参数根据数据格式缩进显示，读起来更加清晰。
        # ensure_ascii=True：默认输出ascii码，如果把这个该成False,就可以输出中文。
        # dump()比dumps()就是多了一个fp的文件参数


if __name__ == '__main__':
    # 爬取百度百科中《青春有你2》中参赛选手信息，返回html
    html = catch_html_data()
    # print(html)
    # 解析html,得到选手信息，保存为json文件
    parse_html_data(html)
